/*
 * @Author: Crism
 * @Date: 2018-08-10 10:10:11
 * @LastEditors: Crism
 * @LastEditTime: 2018-08-10 10:10:11
 * @Description: 
 * @Email: crism@qq.com
 */

const mysql = require('promise-mysql');

const _pool = Symbol('pool');

function sleep(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
}

function DB(db_config) {
    this[_pool] = mysql.createPool(db_config);
}


DB.prototype.query = async function (sql, cnt = 0) {
    let res = '';
    let flag = true;
    let conn = null;

    // await this[_pool].getConnection()
    //     .then((connection) => {
    //         conn = connection;
    //         return connection.query(sql);
    //     }).then((rows) => {
    //         res = rows;
    //     }).catch((err) => {
    //         flag = false;
    //         res = err;
    //     })

    // if (conn) {
    //     this[_pool].releaseConnection(conn);
    // }


    await this[_pool].query(sql)
        .then(rows => {
            res = rows;
        }).catch(err => {
            flag = false;
            res = err;
        })


    if (!flag && cnt < 3) {
        //请求失败后会再发送请求,最多请求3次
        cnt++;
        let err_msg = '数据库请求失败' + cnt + '次，sql:' + sql + ',err:' + res;
        console.trace(err_msg);
        if (err_msg.indexOf('The server closed the connection') < 0 && err_msg.indexOf('Handshake inactivity timeout') < 0) {
            global.ErrorLog.write(err_msg);
        }
        await sleep(300);
        res = await this.query(sql, cnt);
    }


    return res;  
};

DB.prototype.queryOne = async function (sql) {
    let rows = await this.query(sql);
    if (rows instanceof Array && rows.length > 0) {
        return rows[0];
    } else {
        return null;
    }
};


DB.prototype.queryNum = async function (sql) {
    let res = await this.query(sql);
    let num = res['affectedRows'] || -1;
    return num;
};


DB.prototype.queryInsertId = async function (sql) {
    let res = await this.query(sql);
    let num = res.insertId || -1;
    return num;
};


DB.prototype.escape = function (value) {
    return this[_pool].escape(value);
}

DB.prototype.getConnection = async function () {
    let conn = null
    await this[_pool].getConnection()
        .then((connection) => {
            conn = connection;
        }).catch((err) => {
            let err_msg = '数据库获取连接失败,err:' + err;
            console.trace(err_msg);
            global.ErrorLog.write(err_msg);
        });
    return conn;
}

DB.prototype.releaseConnection = function (connection) {
    this[_pool].releaseConnection(connection);
}

module.exports = DB;
